{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "原文代码作者：https://github.com/wzyonggege/statistical-learning-method\n",
    "\n",
    "中文注释制作：机器学习初学者(微信公众号：ID:ai-start-com)\n",
    "\n",
    "配置环境：python 3.6\n",
    "\n",
    "代码全部测试通过。\n",
    "![gongzhong](../gongzhong.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第6章 逻辑斯谛回归"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "LR是经典的分类方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "回归模型：$f(x) = \\frac{1}{1+e^{-wx}}$\n",
    "\n",
    "其中wx线性函数：$wx =w_0*x_0 + w_1*x_1 + w_2*x_2 +...+w_n*x_n,(x_0=1)$\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import exp\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "from sklearn.datasets import load_iris\n",
    "from sklearn.model_selection import train_test_split"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# data\n",
    "def create_data():\n",
    "    iris = load_iris()\n",
    "    df = pd.DataFrame(iris.data, columns=iris.feature_names)\n",
    "    df['label'] = iris.target\n",
    "    df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']\n",
    "    data = np.array(df.iloc[:100, [0,1,-1]])\n",
    "    # print(data)\n",
    "    return data[:,:2], data[:,-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "X, y = create_data()\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class LogisticReressionClassifier:\n",
    "    def __init__(self, max_iter=200, learning_rate=0.01):\n",
    "        self.max_iter = max_iter\n",
    "        self.learning_rate = learning_rate\n",
    "        \n",
    "    def sigmoid(self, x):\n",
    "        return 1 / (1 + exp(-x))\n",
    "\n",
    "    def data_matrix(self, X):\n",
    "        data_mat = []\n",
    "        for d in X:\n",
    "            data_mat.append([1.0, *d])\n",
    "        return data_mat\n",
    "\n",
    "    def fit(self, X, y):\n",
    "        # label = np.mat(y)\n",
    "        data_mat = self.data_matrix(X) # m*n\n",
    "        self.weights = np.zeros((len(data_mat[0]),1), dtype=np.float32)\n",
    "\n",
    "        for iter_ in range(self.max_iter):\n",
    "            for i in range(len(X)):\n",
    "                result = self.sigmoid(np.dot(data_mat[i], self.weights))\n",
    "                error = y[i] - result \n",
    "                self.weights += self.learning_rate * error * np.transpose([data_mat[i]])\n",
    "        print('LogisticRegression Model(learning_rate={},max_iter={})'.format(self.learning_rate, self.max_iter))\n",
    "\n",
    "    # def f(self, x):\n",
    "    #     return -(self.weights[0] + self.weights[1] * x) / self.weights[2]\n",
    "\n",
    "    def score(self, X_test, y_test):\n",
    "        right = 0\n",
    "        X_test = self.data_matrix(X_test)\n",
    "        for x, y in zip(X_test, y_test):\n",
    "            result = np.dot(x, self.weights)\n",
    "            if (result > 0 and y == 1) or (result < 0 and y == 0):\n",
    "                right += 1\n",
    "        return right / len(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LogisticRegression Model(learning_rate=0.01,max_iter=200)\n"
     ]
    }
   ],
   "source": [
    "lr_clf = LogisticReressionClassifier()\n",
    "lr_clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9666666666666667"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lr_clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x149966d7908>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x_ponits = np.arange(4, 8)\n",
    "y_ = -(lr_clf.weights[1]*x_ponits + lr_clf.weights[0])/lr_clf.weights[2]\n",
    "plt.plot(x_ponits, y_)\n",
    "\n",
    "#lr_clf.show_graph()\n",
    "plt.scatter(X[:50,0],X[:50,1], label='0')\n",
    "plt.scatter(X[50:,0],X[50:,1], label='1')\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## sklearn\n",
    "\n",
    "### sklearn.linear_model.LogisticRegression\n",
    "\n",
    "solver参数决定了我们对逻辑回归损失函数的优化方法，有四种算法可以选择，分别是：\n",
    "- a) liblinear：使用了开源的liblinear库实现，内部使用了坐标轴下降法来迭代优化损失函数。\n",
    "- b) lbfgs：拟牛顿法的一种，利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。\n",
    "- c) newton-cg：也是牛顿法家族的一种，利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。\n",
    "- d) sag：即随机平均梯度下降，是梯度下降法的变种，和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度，适合于样本数据多的时候。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "clf = LogisticRegression(max_iter=200)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,\n",
       "          intercept_scaling=1, max_iter=200, multi_class='ovr', n_jobs=1,\n",
       "          penalty='l2', random_state=None, solver='liblinear', tol=0.0001,\n",
       "          verbose=0, warm_start=False)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf.fit(X_train, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9666666666666667"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "clf.score(X_test, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.94474283 -3.29077674]] [-0.53064339]\n"
     ]
    }
   ],
   "source": [
    "print(clf.coef_, clf.intercept_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x1499696b710>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x_ponits = np.arange(4, 8)\n",
    "y_ = -(clf.coef_[0][0]*x_ponits + clf.intercept_)/clf.coef_[0][1]\n",
    "plt.plot(x_ponits, y_)\n",
    "\n",
    "plt.plot(X[:50, 0], X[:50, 1], 'bo', color='blue', label='0')\n",
    "plt.plot(X[50:, 0], X[50:, 1], 'bo', color='orange', label='1')\n",
    "plt.xlabel('sepal length')\n",
    "plt.ylabel('sepal width')\n",
    "plt.legend()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
